package cn.com.sinux.spring.utils;

import cn.com.sinux.spring.exception.ServiceException;
import org.apache.commons.lang.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ConvertUtils {

    /**
     * 分割字符串生成list
     *
     * @param ids 字符串
     * @param spr 分割符号
     * @return 资源
     */
    public static List<String> loadStringList(String ids, char spr) {
        if (StringUtils.isBlank(ids)) {
            return new LinkedList<String>();
        }
        String[] idArray = StringUtils.split(ids, spr);
        return arrayToList(idArray);
    }

    public static class FieldAndObject {
        private Field field;
        private Object object;
        private boolean isList;

        public Object getObject() {
            return object;
        }

        public void setObject(Object object) {
            this.object = object;
        }

        public FieldAndObject(Field field, Object obj) throws Exception {
            this.field = field;
            this.isList = this.field.getType().equals(List.class);
            this.object = obj;
        }

        public void setValue(Object value) throws Exception {
            if (!isList) {
                field.setAccessible(true);
                field.set(object, value);
                field.setAccessible(false);
            } else {
                //先拿出list，判断是否为null，为null则构造，不为null则添加
                field.setAccessible(true);
                List objects = (List) field.get(object);
                if (objects == null) {
                    objects = new ArrayList();
                }
                objects.add(value);
                field.set(object, objects);
                field.setAccessible(false);
            }
        }
    }

    private static void deepObject(List<FieldAndObject> fieldAndObjects, Object obj, String property) throws Exception {
        int pos = property.indexOf(".");
        if (pos == -1) {
            fieldAndObjects.add(new FieldAndObject(obj.getClass().getDeclaredField(property), obj));
        } else {
            Field field = obj.getClass().getDeclaredField(property.substring(0, pos));
            fieldAndObjects.add(new FieldAndObject(field, obj));
            deepObject(fieldAndObjects, createInstance(field), property.substring(pos + 1));
        }
    }

    public static Object createInstance(Field field) throws Exception {
        if (field.getType().equals(List.class)) {
            ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
            if (parameterizedType != null && parameterizedType.getActualTypeArguments() != null && parameterizedType.getActualTypeArguments().length > 0) {
                Class aClass = (Class) parameterizedType.getActualTypeArguments()[0];
                return aClass.newInstance();
            } else {
                throw new ServiceException("要为list执行批量上传必须使用泛型");
            }
        } else {
            return field.getType().newInstance();
        }
    }

    public static String doConvertMsg(String msg, final List<String> args) {
        if (StringUtils.isBlank(msg)) {
            return msg;
        }
        String content = msg;
        if (ValidatorUtils.isArrayNotEmpty(args)) {
            final int len = args.size();
            if (len > 0) {
                content = ConvertUtils.replace(msg, "\\{\\d+\\}", new ReplaceOperate() {

                    public String replace(int i, String pattern) {
                        return i > len - 1 ? "" : args.get(i);
                    }
                });
            }
        }
        return content;
    }

//    private static void buildListFiled(){
//
//    }

    public static void buildProperty(Object o, String property, Object value) throws Exception {
        List<FieldAndObject> fieldAndObjects = new ArrayList<FieldAndObject>();
        deepObject(fieldAndObjects, o, property);
        Object obj = value;
        for (int i = fieldAndObjects.size() - 1; i >= 0; i--) {
            fieldAndObjects.get(i).setValue(obj);
            obj = fieldAndObjects.get(i).getObject();
        }
    }

    /**
     * 分割字符串生成list
     *
     * @param ids 字符串
     * @param spr 分割符号
     * @return 资源
     */
    public static List<String> loadStringList(String ids, String spr) {
        if (StringUtils.isBlank(ids)) {
            return new LinkedList<String>();
        }
        String[] idArray = StringUtils.split(ids, spr);
        return arrayToList(idArray);
    }

    /**
     * @param array 数组
     * @return 集合
     */
    private static List<String> arrayToList(String[] array) {
        List<String> results = new LinkedList<String>();
        Collections.addAll(results, array);
        return results;
    }


    public static List<Integer> loadIntegerList(String ids, char spr) {
        if (StringUtils.isBlank(ids)) {
            return new ArrayList<Integer>();
        }
        String[] idArray = StringUtils.split(ids, spr);
        List<Integer> integerIds = new ArrayList<Integer>(idArray.length);
        for (String id : idArray) {
            integerIds.add(Integer.parseInt(id.trim()));
        }
        return integerIds;
    }

    public static Set<String> loadStringSet(String ids, char spr) {
        if (StringUtils.isBlank(ids)) {
            return new HashSet<String>();
        }
        return new HashSet<String>(loadStringList(ids, spr));
    }

    public static Set<Integer> loadIntegerSet(String ids, char spr) {
        if (StringUtils.isBlank(ids)) {
            return new HashSet<Integer>();
        }
        return new HashSet<Integer>(loadIntegerList(ids, spr));
    }

    /**
     * 获取like的字符串
     *
     * @param value        lyz
     * @param defaultValue morenzhi
     * @return %lyz%
     */
    public static String makeLikeString(String value, String defaultValue) {
        if (StringUtils.isBlank(value)) {
            return defaultValue;
        }
        return "%" + value + "%";
    }

    /**
     * 获取pinyin分割的字符串
     *
     * @param value        lyz
     * @param defaultValue 默认值
     * @return l%y%z%
     */
    public static String makeLikeNameString(String value, String defaultValue) {
        if (StringUtils.isBlank(value)) {
            return defaultValue;
        }
        StringBuilder stringBuilder = new StringBuilder(200);
        for (int i = 0; i < value.length(); i++) {
            stringBuilder.append(value.charAt(i)).append("%");
        }
        return stringBuilder.toString();
    }


    /**
     * 将集合拆分并按字符生成字符串
     *
     * @param set 集合
     * @param spr 分隔符
     * @return 字符串你
     */
    public static String toString(Set<String> set, char spr) {
        if (!ValidatorUtils.isArrayNotEmpty(set)) {
            return StringUtils.EMPTY;
        }
        StringBuilder stringBuilder = new StringBuilder(20 * set.size() + 10);
        for (String _str : set) {
            stringBuilder.append(_str).append(spr);
        }
        int length = stringBuilder.length();
        stringBuilder.delete(length - 1, length);
        return stringBuilder.toString();
    }

    /**
     * 匹配并返回所有满足正则表达式的内容
     *
     * @param input 在字符串中找到满足正则包大事的字符串
     * @param reg   正则
     * @return 集合
     */
    public static List<String> find(String input, String reg) {
        Pattern pattern = Pattern.compile(reg);
        Matcher matcher = pattern.matcher(input);
        List<String> finds = new LinkedList<String>();
        while (matcher.find()) {
            finds.add(matcher.group());
        }
        return finds;
    }

    public static void cast(Object src, Object desc) {
        if (!src.getClass().equals(desc.getClass().getSuperclass()) || src.getClass() == Object.class) {
            return;
        }
        BeanUtils.copyProperties(src, desc);
    }

    public static String replaceWithReg(String input, String reg, ReplaceOperate replaceOperate) {
        Pattern pattern = Pattern.compile(reg);
        Matcher matcher = pattern.matcher(input);
        String replacedStr = input;
        int i = 0;
        while (matcher.find()) {
            String group = matcher.group();
            replacedStr = StringUtils.replace(replacedStr, group, replaceOperate.replace(i, group));
            i++;
        }
        return replacedStr;
    }


    public static String[] splitBlank(String input) {
        return input.split("\\s+");
    }

    public static <E> List<E> convertTo(Collection<? extends E> collections) {
        return new ArrayList<E>(collections);
    }

    public static <E, F extends E> List<F> convertToP(Collection<E> collections) {
        List<F> ff = new ArrayList<F>();
        try {
            for (E e : collections) ff.add((F) e);
        } catch (Exception ex) {
            return Collections.emptyList();
        }
        return ff;
    }

    public static <E> List<E> convertTo(E[] array) {
        List<E> answer = new ArrayList<E>();
        if (array == null || array.length == 0) {
            return answer;
        }
        for (E e : array) {
            answer.add(e);
        }

        return answer;
    }

    public static <E> Set<E> convertToSet(Collection<? extends E> collections) {
        return new HashSet<E>(collections);
    }

    /**
     * 替换并返回根据正则表达式替换后的内容
     */
    public static String replace(String input, String reg, ReplaceOperate replaceOperate) {
        /*Pattern pattern = Pattern.compile(reg);
        Matcher matcher = pattern.matcher(input);
        StringBuffer sb = new StringBuffer(4000);
        int i = 0;
        while (matcher.find()) {
            String group = matcher.group();
            matcher.appendReplacement(sb, replaceOperate.replace(i, group));
            i++;
        }
        matcher.appendTail(sb);
        return sb.toString();*/
        return replaceWithReg(input, reg, replaceOperate);
    }

    private static List<Class> BASE_TYPES = Arrays.<Class>asList(
            String.class, Integer.class, Long.class, Date.class, BigDecimal.class,
            Short.class, Boolean.class, Character.class
    );

    public static Set<String> getFiledName(Class t) {
        Field[] fields = t.getDeclaredFields();
        Set<String> st = new HashSet<String>();
        for (Field field : fields) {
            if (BASE_TYPES.contains(field.getType())) {
                st.add(field.getName());
            }
        }
        return st;
    }

    public static List<Integer> parseNumber(int number, int w) {
        List<Integer> size = new ArrayList<Integer>();
        size.add(number % w);
        while (true) {
            number /= w;
            if (number == 0) {
                break;
            } else {
                size.add(number % w);
            }
        }
        Collections.reverse(size);
        return size;
    }

    public static interface RepeatCompare<T> {
        public String getCompareProperty(T t);
    }

    public static <T> List<T> removeRepeat(List<T> tes, RepeatCompare<T> ts) {
        Set<String> store = new HashSet<String>();
        List<T> result = new LinkedList<T>();
        for (T t : tes) {
            String flag = ts.getCompareProperty(t);
            if (!store.contains(flag)) {
                store.add(flag);
                result.add(t);
            }
        }
        return result;
    }

    public static List<String> enumToList(Enum[] enums) {
        List<String> list = new LinkedList<String>();
        for (Enum en : enums) {
            list.add(en.name());
        }
        return list;
    }

    public static String replace(String pro) {
        if (StringUtils.isBlank(pro)) {
            return pro;
        }
        String regx = "([<>\"])+";
        Pattern p = Pattern.compile(regx);
        Matcher matcher = p.matcher(pro);
        if (!matcher.matches()) {
            return pro;
        }
        StringBuffer replaces = new StringBuffer();
        while (matcher.find()) {
            String key = matcher.group(1);
            if ("<".equals(key)) {
                matcher.appendReplacement(replaces, "&lt;");
            } else if (">".equals(key)) {
                matcher.appendReplacement(replaces, "&gt;");
            } else if ("&".equals(key)) {
                matcher.appendReplacement(replaces, "&amp;");
            } else if ("\"".equals(key)) {
                matcher.appendReplacement(replaces, "&quot;");
            } else {
                matcher.appendReplacement(replaces, key);
            }
        }
        matcher.appendTail(replaces);
        ////replaceResult.setResult(sb);//back/
        return replaces.toString();
    }


    public static void main(String[] args) throws Exception {
        Pattern pattern = Pattern.compile("<tr>");
        Pattern pattern2 = Pattern.compile("<td\\S?[^>]*>([^<]*)<\\/td>");
        String str = "<table name=\"parameterValue\" data-id=\"f-component\" class=\"normal-table\">\n" +
                "    <tbody><tr>\n" +
                "        <td></td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td><td>11</td><td>12</td><td>13</td><td>14</td><td>15</td>\n" +
                "    </tr>\n" +
                "    <tr>\n" +
                "        <td>时间（min）</td><td contenteditable=\"true\">1</td><td contenteditable=\"true\">4</td><td contenteditable=\"true\">2</td><td contenteditable=\"true\">4</td><td contenteditable=\"true\">5</td><td contenteditable=\"true\">6</td><td contenteditable=\"true\">7</td><td contenteditable=\"true\">8</td><td contenteditable=\"true\">9</td><td contenteditable=\"true\">0</td><td contenteditable=\"true\">11</td><td contenteditable=\"true\">12</td><td contenteditable=\"true\">13</td><td contenteditable=\"true\">14</td><td contenteditable=\"true\">5</td>\n" +
                "    </tr>\n" +
                "    <tr>\n" +
                "        <td>温度（℃）</td><td contenteditable=\"true\">2</td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td>\n" +
                "    </tr>\n" +
                "    <tr>\n" +
                "        <td>PID(0/1/2/3）</td><td contenteditable=\"true\">3</td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td><td contenteditable=\"true\"></td>\n" +
                "    </tr>\n" +
                "</tbody></table>";
        Matcher matcher = pattern.matcher(str);
        List<String> values = new ArrayList<String>();
        int tr = 0;
        while (matcher.find()) {
            String group = matcher.group();
            tr++;
        }
        Matcher matcher2 = pattern2.matcher(str);
        while (matcher2.find()) {
            String group = matcher2.group(1);
            values.add(group);
        }
        System.out.println(values);
    }


}
